﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Ionic.Utils.Zip;
using Utilities;

namespace SilverLightStreamingInterface
{
    /// <summary>
    /// This class takes care of preparing a directory for upload to SilverLight.
    /// </summary>
    public class PackagePrep
    {
        public string ZIPFileLocation { get; set; }

        public PackagePrep()
        {
            ZIPFileLocation = Path.GetTempPath() + "\\ZipFilesTemp";
        }

        /// <summary>
        /// Only allow files that are good for upload to exist!
        /// </summary>
        /// <param name="pack"></param>
        public void CleanPackage(SLPackage pack)
        {
            var allgoodextensions = from e in Settings.ValidFileTypes
                                    select "." + e;
            CleanFiles(pack.PackageDirectory, allgoodextensions.ToArray());
        }

        /// <summary>
        /// Remove all the "bad" files.
        /// </summary>
        /// <param name="directoryInfo"></param>
        private void CleanFiles(DirectoryInfo directoryInfo, string[] goodFiles)
        {
            foreach (var f in directoryInfo.GetFiles())
            {
                if (!goodFiles.Contains(f.Extension))
                {
                    f.Delete();
                }
            }

            foreach (var d in directoryInfo.GetDirectories())
            {
                CleanFiles(d, goodFiles);
            }
        }

        /// <summary>
        /// Given a package, zip it up!
        /// </summary>
        /// <param name="pack"></param>
        public SLPackage ZipPackage(SLPackage pack)
        {
            FileInfo outZip = new FileInfo(ZIPFileLocation + "\\" + pack.Name + ".zip");
            FileInfo outToken = new FileInfo(ZIPFileLocation + "\\" + pack.Name + ".token");

            if (outToken.Exists)
            {
                pack.ZIPFile = outZip;
                return pack;
            }

            ///
            /// Make the zip file!
            ///

            if (!outZip.Directory.Exists)
            {
                outZip.Directory.Create();
            }
            
            string currentWorkingDir = null;
            try
            {
                currentWorkingDir = Environment.CurrentDirectory;
                Environment.CurrentDirectory = pack.PackageDirectory.FullName;
                using (ZipFile outzip = new ZipFile(outZip.FullName))
                {
                    ZipFiles(outzip, Environment.CurrentDirectory, new DirectoryInfo("."));
                    outzip.Save();
                }
            }
            finally
            {
                if (currentWorkingDir != null)
                {
                    Environment.CurrentDirectory = currentWorkingDir;
                }
            }

            ///
            /// And make the token since it went well!
            ///

            pack.ZIPFile = outZip;
            using (TextWriter wr = outToken.CreateText())
            {
                wr.WriteLine("Done ok!");
                wr.Close();
            }

            return pack;
        }

        /// <summary>
        /// Recursively add files to the ZIP archive.
        /// </summary>
        /// <param name="outzip"></param>
        /// <param name="p"></param>
        /// <param name="directoryInfo"></param>
        private void ZipFiles(ZipFile outzip, string relativebase, DirectoryInfo directoryInfo)
        {
            foreach (var f in directoryInfo.GetFiles())
            {
                string fullpath = f.FullName;
                string relativepath = fullpath.Substring(relativebase.Length+1);
                outzip.AddFile(relativepath);
            }

            foreach (var d in directoryInfo.GetDirectories())
            {
                ZipFiles(outzip, relativebase, d);
            }
        }

        /// <summary>
        /// Create an html file that can be uploaded to any-old web server and used to access
        /// the SL project that is connected with this guy.
        /// </summary>
        /// <param name="pack"></param>
        public FileInfo CreateSLWebFile(SLPackage pack, string userID, string meetingTitle)
        {
            FileInfo output = new FileInfo(pack.PackageDirectory + "\\ViewConferenceSLS.html");
            Settings.TemplateHTML.CopyTo(output.FullName, true);

            /// Not the most elegant. But it works for this small file.
            output.ReplaceText("USERID", userID);
            output.ReplaceText("SLAPPNAME", pack.Name);
            output.ReplaceText("MEETINGTITLE", meetingTitle);

            return output;
        }
    }
}
